#pragma once


#include "ArgbPixel.h"


class CLayer;


class CColorBuffer
{
public: 
	CColorBuffer();
	~CColorBuffer();
	struct CColorBufferEntry * GetBuffer();
	HRESULT Init(XINT32 nWidth, struct ArgbPixel dwBackgroundColor);
	void Reset();
	void AddScanlineDataColor(XUINT32 dwColor, XUINT32 uBrushBlendAlpha, struct CCoverageInterval * pIntervalStart);
	HRESULT AddScanlineDataBrush(struct IBrushSpan * pIBrushSpan, XUINT32 uBrushBlendAlpha, struct CCoverageInterval * pIntervalStart);
	HRESULT AddScanlineDataLayer(XUINT32 nCPUCore, CLayer * pLayer, XUINT32 uBrushBlendAlpha, struct CCoverageInterval * pIntervalStart);
	HRESULT AddScanlineGrayAlpha(struct IBrushSpan * pBrush, XUINT32 uScanline, XUINT32 uOpacity, XUINT32 nCPUCore, XINT32 iAlphaOffset, XUINT32 cGrayAlphaUnsigned, struct GrayAlpha * pGrayAlpha);
	HRESULT Rasterize(XUINT32 nCPUCore, XINT32 nOffsetX, XINT32 nX, XINT32 nY, XUINT32 uCount, XUINT32 * pdwScanline);
	HRESULT AddScanlineRgbAlpha(struct IBrushSpan * pBrush, XUINT32 uScanline, XUINT32 uOpacity, XUINT32 nCPUCore, XINT32 iAlphaOffset, XUINT32 cAlphaPixels, struct RgbAlpha * pAlphaPixels);
	HRESULT RasterizeClearType(XUINT32 nCPUCore, XINT32 nOffsetX, XINT32 nX, XINT32 nY, XUINT32 uCount, struct ClearTypePixel * pClearTypeScanline);
protected: 
	struct CColorBufferEntry * SkipEqualBrushSegments(struct CColorBufferEntry * pColorBuffer, XINT32 nXEnd);
	void InsertEntry(struct CColorBufferEntry * pColorBuffer, XINT32 nX);
	struct CColorBufferBrushSpan * NewBrushSpan();
	HRESULT PushBrushSpan(struct CColorBufferEntry * pColorBuffer, struct IBrushSpan * pIBrushSpan, XUINT32 uBrushAlpha);
	HRESULT PushBrushSpanList(struct CColorBufferEntry * pColorBufferDestination, struct CColorBufferEntry * pColorBufferSourceEntry);
	HRESULT PushBrushSpanLayer(struct CColorBufferEntry * pColorBufferDestination, struct CColorBufferEntry * pColorBufferLayer, struct IBrushSpan * pIBrushSpan, XUINT32 uGrayAlpha);
	HRESULT CloneBrushStack(struct CColorBufferBrushSpan * pBrushSpanSource, struct CColorBufferBrushSpan * * ppBrushSpanTarget);
	HRESULT RasterizeBrushSpanStack(XUINT32 nCPUCore, XINT32 nOffsetX, struct ArgbPixel colorAbove, struct CColorBufferBrushSpan * pBrushSpan, XINT32 nX, XINT32 nY, XUINT32 uCount, XUINT32 * pdwScanline);
	HRESULT RasterizeBrushSpanStackClearType(XUINT32, XINT32, struct ClearTypePixel &, union CColorBufferBrushSpanSSE2 *, XINT32, XINT32, XUINT32, struct ClearTypePixel *);
	HRESULT GetClearTypeBrushSpanData(struct ClearTypePixel * *);
	XINT32 m_nWidth;
	struct CColorBufferEntry * m_pBuffer;
	struct ArgbPixel * m_pargbBrushSpanData;
	struct CColorBufferBrushSpanChunk * m_pBrushSpanChunkCurrent;
	struct CColorBufferEntry * m_pLastEntry;

	HRESULT (__stdcall *m_pfnInit)(void *, XINT32, ArgbPixel);
	void (__stdcall *m_pfnReset)(void *);
	void (__stdcall *m_pfnAddScanlineDataColor)(void *, XUINT32, XUINT32, CCoverageInterval *);
	HRESULT (__stdcall *m_pfnAddScanlineDataBrush)(void *, IBrushSpan *, XUINT32, CCoverageInterval *);
	HRESULT (__stdcall *m_pfnAddScanlineDataLayer)(void *, XUINT32, CLayer *, XUINT32, CCoverageInterval *);
	HRESULT (__stdcall *m_pfnAddScanlineGrayAlphaColor)(void *, ArgbPixel, XUINT32, XINT32, XUINT32, GrayAlpha *);
	HRESULT (__stdcall *m_pfnAddScanlineGrayAlphaBrush)(void *, IBrushSpan *, XUINT32, XINT32, XUINT32, GrayAlpha *);
	HRESULT (__stdcall *m_pfnRasterize)(void *, XUINT32, XINT32, XINT32, XINT32, XUINT32, XUINT32 *);
	HRESULT (__stdcall *m_pfnAddScanlineRgbAlpha)(void *, IBrushSpan *, XUINT32, XUINT32, XUINT32, XINT32, XUINT32, RgbAlpha *);
	HRESULT (__stdcall *m_pfnAddScanlineRgbAlphaColor)(void *, ArgbPixel, XUINT32, XINT32, XUINT32, RgbAlpha *);
	HRESULT (__stdcall *m_pfnAddScanlineRgbAlphaBrush)(void *, IBrushSpan *, XUINT32, XINT32, XUINT32, RgbAlpha *);
	HRESULT (__stdcall *m_pfnRasterizeClearType)(void *, XUINT32, XINT32, XINT32, XINT32, XUINT32, ClearTypePixel *);

	union CColorBufferEntrySSE2 * m_pBufferSSE2;
	struct CColorBufferBrushSpanChunkSSE2 * m_pBrushSpanChunkCurrentSSE2;
	struct ClearTypePixel * m_pClearTypeBrushSpanData;
	union CColorBufferEntrySSE2 * m_pAllocated;
	struct ClearTypePixel * m_pClearTypeAllocated;
private: 
	static HRESULT _Init(void * _this_, XINT32 nWidth, struct ArgbPixel dwBackgroundColor);
	static HRESULT _Reset(void * _this_);
	static HRESULT _AddScanlineDataColor(void * _this_, XUINT32 uColor, XUINT32 uBrushBlendAlpha, struct CCoverageInterval * pIntervalStart);
	static HRESULT _AddScanlineDataBrush(void * _this_, struct IBrushSpan * pIBrushSpan, XUINT32 uBrushBlendAlpha, struct CCoverageInterval * pIntervalStart);
	static HRESULT _AddScanlineDataLayer(void * _this_, XUINT32 nCPUCore, CLayer * pLayer, XUINT32 uBrushBlendAlpha, struct CCoverageInterval * pIntervalStart);
	static HRESULT _AddScanlineGrayAlphaColor(void * _this_, struct ArgbPixel uColor, XUINT32 uBrushBlendAlpha, XINT32 iAlphaOffset, XUINT32 cGlyphAlphaUnsigned, struct GrayAlpha * pGrayAlpha);
	static HRESULT _AddScanlineGrayAlphaBrush(void * _this_, struct IBrushSpan * pIBrushSpan, XUINT32 uBrushBlendAlpha, XINT32 iAlphaOffset, XUINT32 cGlyphAlphaUnsigned, struct GrayAlpha * pGrayAlpha);
	static HRESULT _Rasterize(void * _this_, XUINT32 nCPUCore, XINT32 nOffsetX, XINT32 nX, XINT32 nScanline, XUINT32 uCount, XUINT32 * pdwScanline);
	static HRESULT _AddScanlineRgbAlpha(void * _this_, struct IBrushSpan * pBrush, XUINT32 uScanline, XUINT32 uOpacity, XUINT32 nCPUCore, XINT32 iAlphaOffset, XUINT32 cGlyphAlphaUnsigned, struct RgbAlpha * pGlyphAlpha);
	static HRESULT _AddScanlineRgbAlphaColor(void * _this_, struct ArgbPixel uColor, XUINT32 uBrushBlendAlpha, XINT32 iAlphaOffset, XUINT32 cGlyphAlphaUnsigned, struct RgbAlpha * pRgbAlpha);
	static HRESULT _AddScanlineRgbAlphaBrush(void * _this_, struct IBrushSpan * pIBrushSpan, XUINT32 uBrushBlendAlpha, XINT32 iAlphaOffset, XUINT32 cGlyphAlphaUnsigned, struct RgbAlpha * pRgbAlpha);
	static HRESULT _RasterizeClearType(void * _this_, XUINT32 nCPUCore, XINT32 nOffsetX, XINT32 nX, XINT32 nScanline, XUINT32 uCount, struct ClearTypePixel * pClearTypeScanLine);

};